package com.yaoyong.yy_demo.module.wechat;

import com.thoughtworks.xstream.XStream;
import com.yaoyong.yy_demo.common.canstant.WechatMessageType;
import org.apache.commons.text.StringEscapeUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 消息处理工具类
 *
 * @author 姚勇
 */
public class WxMessageHelper {

    private static String FORMAT = "<![CDATA[%s]]>";
    private static final XStream XS = new XStream();

    static {
        XS.alias("xml", WxMessage.class);
        XS.alias("item", Article.class);
    }

    /**
     * 解析微信发来的请求（XML）
     *
     * @param request 微信请求
     * @return map 封装了解析结果的Map
     */
    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<>(0);
        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
        System.out.println("获取输入流");
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();
        // 遍历所有子节点
        for (Element e : elementList) {
            System.out.println(e.getName() + "|" + e.getText());
            map.put(e.getName(), e.getText());
        }
        // 释放资源
        inputStream.close();
        return map;
    }

    private static String getUtcTime() {
        // 如果不需要格式,可直接用dt,dt就是当前系统时间
        Date dt = new Date();
        // 设置显示格式
        DateFormat df = new SimpleDateFormat("yyyyMMddhhmm");
        String nowTime = df.format(dt);
        long dd = 0L;
        try {
            dd = df.parse(nowTime).getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return String.valueOf(dd);
    }

    /**
     * 根据消息类型构建响应消息
     *
     * @param map 封装了解析结果的Map
     * @return 响应消息
     */
    public static String buildResponseMessage(Map<String, String> map) {
        WxMessage message = new WxMessage();
        // 发送方帐号（一个OpenID）
        String fromUserName = map.get("FromUserName");
        // 开发者微信号
        String toUserName = map.get("ToUserName");
        // 得到消息类型
        String msgType = map.get("MsgType");
        message.setFromUserName(String.format(FORMAT, toUserName));
        message.setToUserName(String.format(FORMAT, fromUserName));
        message.setMsgType(String.format(FORMAT, msgType));
        message.setCreateTime(getUtcTime());
        System.out.println("FromUserName:" + fromUserName + "ToUserName:" + toUserName + "MsgType:" + msgType);
        // 响应消息
        String responseMessage;
        // 消息类型
        WechatMessageType messageEnumType = WechatMessageType.valueOf(WechatMessageType.class, msgType.toUpperCase());
        switch (messageEnumType) {
            case TEXT:
                // 处理文本消息
                responseMessage = handleTextMessage(map, message);
                break;
            case IMAGE:
                // 处理图片消息
                responseMessage = handleImageMessage(map, message);
                break;
            case VOICE:
                // 处理语音消息
                responseMessage = handleVoiceMessage(map, message);
                break;
            case VIDEO:
                // 处理视频消息
                responseMessage = handleVideoMessage(map, message);
                break;
            case SHORTVIDEO:
                // 处理小视频消息
                responseMessage = handleSmallVideoMessage(map, message);
                break;
            case LOCATION:
                // 处理位置消息
                responseMessage = handleLocationMessage(map, message);
                break;
            case LINK:
                // 处理链接消息
                responseMessage = handleLinkMessage(map, message);
                break;
            case EVENT:
                // 处理事件消息,用户在关注与取消关注公众号时，微信会向我们的公众号服务器发送事件消息,开发者接收到事件消息后就可以给用户下发欢迎消息
                responseMessage = handleEventMessage(map, message);
                break;
            default:
                responseMessage = handleOtherMessage(map, null);
                break;
        }
        // 返回响应消息
        return responseMessage;
    }

    private static String handleOtherMessage(Map<String, String> map, WxMessage message) {
        message.setMsgType("text");
        message.setContent("请回复如下关键词：\\n文本\\n图片\\n语音\\n视频\\n音乐\\n图文");
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static String handleEventMessage(Map<String, String> map, WxMessage message) {
        message.setMsgType("text");
        message.setContent("\t终于等到你了!毕业了也要保持学习哦!\n\t请回复如下关键词：\n\t文本\n\t图片\n\t语音\n\t视频\n\t音乐\n\t图文");
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static String handleLinkMessage(Map<String, String> map, WxMessage message) {
        message.setMsgType("text");
        setContent(message);
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static String handleLocationMessage(Map<String, String> map, WxMessage message) {
        message.setMsgType("text");
        setContent(message);
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static String handleSmallVideoMessage(Map<String, String> map, WxMessage message) {
        message.setMsgType("text");
        setContent(message);
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static String handleVideoMessage(Map<String, String> map, WxMessage message) {
        message.setMsgType("text");
        setContent(message);
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static String handleVoiceMessage(Map<String, String> map, WxMessage message) {
        message.setMsgType("text");
        setContent(message);
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static String handleImageMessage(Map<String, String> map, WxMessage message) {
        message.setMsgType("text");
        setContent(message);
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static String handleTextMessage(Map<String, String> map, WxMessage message) {
        String content = map.get("Content");
        System.out.println(content);
        if ("文本".equals(content)) {
            content = "~喵~,请问客观想要点啥?";
        } else if ("图片".equals(content)) {
            content = "饿哦~,暂时没有图片,试试别的吧!";
        } else if ("语音".equals(content)) {
            content = "饿哦~,试试别的吧!";
        } else if ("视屏".equals(content)) {
            content = "请点击-我要看视屏";
        } else if ("音乐".equals(content)) {
            content = "请点击-我要看音乐";
        } else if ("图文".equals(content)) {
            content = "饿哦~,试试别的吧!";
        } else {
            content = content.replace("吗", "").replace("？", "!").replace("?", "!").trim();
        }
        message.setContent(content);
        String xml = XS.toXML(message);
        return StringEscapeUtils.unescapeXml(xml);
    }

    private static void setContent(WxMessage message) {
        String[] msg = {"你好,需要帮忙吗?", "对不起,服务器忙!", "不要迷恋哥,哥只是个传说!", "请再说一遍!", "厉害了我的哥!", "请给我点赞!", "不点赞,不理你!", "请好好说话!",
                "不想理你!", "持续和我聊天有惊喜哦!"};
        Random r = new Random();
        int i = r.nextInt(msg.length);
        message.setContent(String.format(FORMAT, msg[i]));
    }
}